﻿using System;
using System.Collections.Generic;
using System.IO;
using abilities;
using abilities.effects;
using abilities.targets;
using abilities.templates;
using abilities.triggers;
using abilities.triggers.conditions;
using LitJson;
using UnityEditor;
using UnityEngine;

namespace Dou.Scripts.abilities.Editor
{
    public class TemplateExport
    {
        private static string templateFolder = "../templates";

        static void  whriteEnum<T>(T value,JsonWriter writer)
        {
            writer.Write(string.Join("|",Enum.GetNames(value.GetType())));
        }
        
        
        [MenuItem("Tools/Ability/Export Template")]
        public static void ExportTemplates()
        {
            List<JsonData> effects = new();
            
            JsonMapper.RegisterExporter<AbilityTriggerType>(whriteEnum);
            JsonMapper.RegisterExporter<ParameterValueType>(whriteEnum);
            JsonMapper.RegisterExporter<TargetUnitSide>(whriteEnum);
            JsonMapper.RegisterExporter<TargetUnitType>(whriteEnum);
            JsonMapper.RegisterExporter<DamageType>(whriteEnum); 
            JsonMapper.RegisterExporter<AbilityEffectStackType>(whriteEnum);

            
            foreach (var target in new List<EffectTemplate>() { new EffectImmuneTemplate(),
                         new EffectLimitsTemplate(), new EffectHitDataTemplate(),
                         new EffectParameterModifierTemplate(), new EffectSpawnEffectsTemplate(),
                         new EffectWalkThroughWallsTemplate(), })
            {
                var jd = JsonMapper.ToObject(JsonMapper.ToJson(target));
                jd["type"] = effectTypes[target.GetType()];
                jd["animation"] = JsonMapper.ToObject(JsonMapper.ToJson(new AnimationRule()));
                effects.Add(jd);
            }

            List<JsonData> targets = new();
            foreach (var target in new List<Target>(){ 
                         new TargetCurrent(), new TargetCurrentOrNearest(), 
                         new TargetsAround(), new TargetSelf()})
            {
                var jd = JsonMapper.ToObject(JsonMapper.ToJson(target));
                jd["type"] = targetTypes[target.GetType()];
                targets.Add(jd);
            }
            
            List<JsonData> Conditions = new();
            foreach (var target in new List<AbilityTriggerCondition>(){ new AbilityTriggerConditionChance(),
                         new AbilityTriggerConditionParameterValue(), new AbilityTriggerConditionTargetsAround()})
            {
                var jsondata = JsonMapper.ToObject(JsonMapper.ToJson(target));
                jsondata["type"] = conditionTypes[target.GetType()];
                Conditions.Add(jsondata);
            }
            
            List<JsonData> triggers = new();
            for (int i = 0; i <= (int)AbilityTriggerType.Distanceto; i++)
            {
                var jsondata = JsonMapper.ToObject(JsonMapper.ToJson(new AbilityTriggerTemplate()));
                jsondata["type"] = ((AbilityTriggerType)i).ToString();
                triggers.Add(jsondata);
            }

            WriteJson(effects, "effects.json");
            WriteJson(triggers, "triggers.json");
            WriteJson(Conditions, "Conditions.json");
            WriteJson(targets, "targets.json");
            
            Debug.Log("Exported templates");
            
            JsonMapper.UnregisterExporters();
        }

        static void WriteJson(List<JsonData> _templates, string jsonName)
        {
            JsonData effects = new JsonData();
            foreach (var template in _templates) 
                effects.Add(template);
            File.WriteAllText(Path.Combine(Application.dataPath,templateFolder,jsonName),effects.ToJson());

        }

        private static Dictionary<Type, string> effectTypes = new()
        {
            {typeof(EffectParameterModifierTemplate),"ParameterModifier"},
            {typeof(EffectSpawnEffectsTemplate),"SpawnEffects"},
            {typeof(EffectLimitsTemplate),"EffectLimits"},
            {typeof(EffectHitDataTemplate),"HitData"},
            {typeof(EffectWalkThroughWallsTemplate),"WalkThroughWalls"},
            {typeof(EffectImmuneTemplate),"Immune"}
        };

        private static Dictionary<Type, string> targetTypes = new()
        {
            { typeof(TargetSelf), "Self" },
            { typeof(TargetsAround), "Around" },
            { typeof(TargetCurrent), "Current" },
            { typeof(TargetCurrentOrNearest), "CurrOrNearest" }
        };

        private static Dictionary<Type, string> conditionTypes = new()
        {
            { typeof(AbilityTriggerConditionChance), "Chance" },
            { typeof(AbilityTriggerConditionTargetsAround), "TargetsAround" },
            { typeof(AbilityTriggerConditionParameterValue), "ParameterValue" }

        };
    }
}